package cn.jdy.framework.db.redis;

import java.util.List;
import java.util.Map;
import java.util.Set;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.TransactionBlock;

import cn.jdy.framework.exception.BaseException;

/**
 *   redis 客户基础端操作类
 * @description: redis 客户基础端操作类
 * @author  WuZhiliang
 * @date  2013-07-03 10:10
 */
public class JedisService{

    private JedisPool jedisPool; //jedis 数据库连接池

    public void setJedisPool(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
        checkRedisLiveness();
    }
    /**
     *  返回jedisPool连接池
     * @description: 
	 * @return the jedisPool
	 */
	public JedisPool getJedisPool() {
		return jedisPool;
	}

	// Redis Common Operations
    /**
     *  使用set保存字符串类型值
     * @description: 
     * @param key  键
     * @param value 字符串类型值
     * @return isok ok-执行成功
     */
    public String set(String key,String value) {
        Jedis jedis = getResource();
        String isok = jedis.set(key, value);
        returnResource(jedis);
        return isok;
    }
	/**
	 *  添加key value 字节 序列化
	 * @description: 
	 * @param key
	 * @param value
	 * @return isok ok-执行成功
	 */
	public String set(byte[]key,byte[] value) {
		 Jedis jedis = getResource();
	     String isok = jedis.set(key, value);
	     returnResource(jedis);
	    return isok;
	}
	/**
	 *  添加 key value (String)  并设置key存活时间 
	 * @description: 
	 * @param key
	 * @param value
	 * @param liveTime
	 * @return isok ok-执行成功
	 */
	public String set(String key, String value, int liveTime) {
		Jedis jedis = getResource();
	     String isok = jedis.set(key, value);
	     jedis.expire(key, liveTime);
	     returnResource(jedis);
	    return isok;
	}
	/**
	 *  添加 key value 字节序列化 并设置key存活时间 
	 * @description: 
	 * @param key   
	 * @param value  
	 * @param liveTime
	 * @return isok ok-执行成功
	 */
	public String set(byte[] key, byte[] value, int liveTime) {
		Jedis jedis = getResource();
	     String isok = jedis.set(key, value);
	     jedis.expire(key, liveTime);
	     returnResource(jedis);
	    return isok;
	}
    /**
     *  使用get获取字符串类型值
     * @description: 
     * @param key  键
     * @return value
     */
    public String get(String key) {
        Jedis jedis = getResource();
        String value = jedis.get(key);
        returnResource(jedis);
        return value;
    }
	/**
	 *  通过key 获取value byte[]
	 * @description: 
	 * @param key
	 * @return byte[]
	 */
	public byte[] get(byte[] key) {
		 Jedis jedis = getResource();
		 byte[] value = jedis.get(key);
	     returnResource(jedis);
	     return value;
	}
    /**
     *  自增每次加1
     * @description: 相当于 ++
     * @param key
     * @return incr Long 
     */
    public Long incr(String key) {
        Jedis jedis = getResource();
        Long incr = jedis.incr(key);
        returnResource(jedis);
        return incr;
    }
    /**
     *  开启事物进行操作    例如   new TransactionBlock() {
            public void execute() throws JedisException {
                del(key);
                hmset(key, hashedObject);
            }
        }
     * @description: 
     * @param transaction
     * @return
     */
    public List<Object> multi(TransactionBlock transaction) {
        Jedis jedis = getResource();
        List<Object> multi = jedis.multi(transaction);
        returnResource(jedis);
        return multi;
    }
    /**
     *  删除 key
     * @description: 
     * @param key
     * @return
     */
    public Long delete(String key) {
        Jedis jedis = getResource();
        Long del = jedis.del(key);
        returnResource(jedis);
        return del;
    }
	/**
	 *  根据key删除 byte[]
	 * @description: 
	 * @param key
	 * @return 
	 */
	public Long delete(byte[] key){
		Jedis jedis = getResource();
        Long del = jedis.del(key);
        returnResource(jedis);
        return del;
	}
    /**
	 *  删除多个key  
	 * @description: 
	 * @param list 里面存放String型 key
	 * @return 
	 */
	public Long delete(String...keys) {
		Jedis jedis = getResource();
        jedis.del(keys);
         returnResource(jedis);
		return null;
	}
    // Redis Hash Operations
   /**
    *  保存  hashmap 类型数据
    * @description: 
    * @param key
    * @param hashMap
    * @return
    */
    public String hmset(String key,Map<String, String> hashMap) {
        Jedis jedis = getResource();
        String isok = jedis.hmset(key, hashMap);
        returnResource(jedis);
        return isok;
    }
    /**
     *  根据key 获取HashMap里面所有键值对
     * @description: 
     * @param key
     * @return HashMap
     */
    public Map<String, String> hgetAll(String key) {
        Jedis jedis = getResource();
        Map<String, String> hashMap = jedis.hgetAll(key);
        returnResource(jedis);
        return hashMap;
    }
    /**
     *  获取HashMap 里面的键对应的值
     * @description: 
     * @param key
     * @param field
     * @return value
     */
    public String hget(String key,String field) {
        Jedis jedis = getResource();
        String value = jedis.hget(key, field);
        returnResource(jedis);
        return value;
    }
    /**
     *  删除HashMap 里面的键为field的键值对
     * @description: 
     * @param key
     * @param field
     * @return 删除元素个数
     */
    public Long hdel(String key,String field) {
        Jedis jedis = getResource();
        Long hdel = jedis.hdel(key, field);
        returnResource(jedis);
        return hdel;
    }
    /**
     *  获取HashMap的大小
     * @description: 
     * @param key
     * @return 返回hashMap 的长度
     */
    public Long hlen(String key) {
        Jedis jedis = getResource();
        Long hlen = jedis.hlen(key);
        returnResource(jedis);
        return hlen;
    }
    /**
     *  获取HashMap 里面所有的键
     * @description: 
     * @param key
     * @return 返回key对应hashmap中所有的键
     */
    public Set<String> hkeys(String key) {
        Jedis jedis = getResource();
        Set<String> hkeys = jedis.hkeys(key);
        returnResource(jedis);
        return hkeys;
    }
    // Redis List Operations
   /**
    *  在key 对应的List的头部添加字符串元素
    * @description: 
    * @param key
    * @param value
    * @return
    */
    public Long rpush(String key,String value) {
        Jedis jedis = getResource();
        Long len = jedis.rpush(key, value);
        returnResource(jedis);
        return len;
    }
	/**
	 *  把所有数据添加到一个列表中,并且设置列表的存活时间
	 * @description: 
	 * @param key 列表名
	 * @param values 数据
	 * @param liveTime 存活时间--单位(秒)
	 * @return
	 */
	public Long rpush(byte key[], byte[] values, int liveTime){
		Jedis jedis = getResource();
        Long len = jedis.lpush(key, values);
        jedis.expire(key, liveTime);
        returnResource(jedis);
        return len;
	}
    /**
     *  在key 对应的List的尾部添加字符串元素
     * @description: 
     * @param key
     * @param value
     * @return
     */
    public Long lpush(String key,String value) {
        Jedis jedis = getResource();
        Long len = jedis.lpush(key, value);
        returnResource(jedis);
        return len;
    }
    /**
	 *  把所有数据添加到一个列表中,并且设置列表的存活时间
	 * @description: 
	 * @param key 列表名
	 * @param values 数据
	 * @param liveTime 存活时间--单位(秒)
	 * @return
	 */
	public Long lpush(byte key[], byte[] values, int liveTime) {
		Jedis jedis = getResource();
        Long len = jedis.lpush(key, values);
        jedis.expire(key, liveTime);
        returnResource(jedis);
        return len;
	}
    /**
     *  保留指定key 的值范围内的数据
     * @description: 
     * @param key
     * @param start
     * @param end
     */
    public  void ltrim(String key,int start, int end){
    	Jedis jedis = getResource();
        jedis.ltrim(key, start, end);
        returnResource(jedis);
    }
    /**
     *  从list的头部删除元素，并返回删除元素 
     * @description: 
     * @param key
     * @param index
     * @param value
     * @return
     */
    public String lpop(String key) {
        Jedis jedis = getResource();
        String value = jedis.lpop(key);
        returnResource(jedis);
        return value;
    }
    /**
     *  设置list中指定下标的元素值(下标从0开始)
     * @description: 
     * @param key
     * @param index
     * @param value
     * @return
     */
    public String rpop(String key) {
        Jedis jedis = getResource();
        String value = jedis.rpop(key);
        returnResource(jedis);
        return value;
    }
    /**
     *  设置list中指定下标的元素值(下标从0开始)
     * @description: 
     * @param key
     * @param index
     * @param value
     * @return
     */
    public String lset(String key,int index, String value) {
        Jedis jedis = getResource();
        String isok = jedis.lset(key, index, value);
        returnResource(jedis);
        return isok;
    }
    /**
     *  返回名称为key的list中index位置的元素
     * @description: 
     * @param key
     * @param index
     * @return
     */
    public String lindex(String key,int index) {
        Jedis jedis = getResource();
        String lindex = jedis.lindex(key, index);
        returnResource(jedis);
        return lindex;
    }
    /**
     *  返回key对应list的长度 
     * @description: 
     * @param key
     * @return
     */
    public Long llen(String key) {
        Jedis jedis = getResource();
        Long llen = jedis.llen(key);
        returnResource(jedis);
        return llen;
    }
    /**
     *  从key对应list中删除count个和value相同的元素。 
			count>0时，按从头到尾的顺序删除
	 * @description: 
     * @param key
     * @param count
     * @param value
     * @return
     */
    public Long lrem(String key,int count, String value) {
        Jedis jedis = getResource();
        Long lrem = jedis.lrem(key, count, value);
        returnResource(jedis);
        return lrem;
    }
    /**
     *  返回KEY对应List 中的元素
     * @description: 
     * @param key
     * @param start  开始位置  起始位为0
     * @param end  结束位置 -1代表全部
     * @return
     */
    public List<String> lrange(String key,int start, int end) {
        Jedis jedis = getResource();
        List<String> lrange = jedis.lrange(key, start, end);
        returnResource(jedis);
        return lrange;
    }
 // Redis Set Operations
    /**
     *  给set 添加元素
     * @description: 
     * @param key
     * @param member
     * @return
     */
    public Long sadd(String key,String member) {
        Jedis jedis = getResource();
        Long reply = jedis.sadd(key, member);
        returnResource(jedis);
        return reply;
    }
    /**
     *  移除 set 里面的元素
     * @description: 
     * @param key
     * @param member
     * @return
     */
    public Long srem(String key,String member) {
        Jedis jedis = getResource();
        Long reply = jedis.srem(key, member);
        returnResource(jedis);
        return reply;
    }
    /**
     *  获取set 里面的元素
     * @description: 
     * @param key
     * @return
     */
    public Set<String> smembers(String key) {
        Jedis jedis = getResource();
        Set<String> members = jedis.smembers(key);
        returnResource(jedis);
        return members;
    }
 // Redis SortedSet Operations
    /**
     *  获取key对应zset 中的元素
     * @description: 
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set<String> zrange(String key,int start, int end) {
        Jedis jedis = getResource();
        Set<String> zrange = jedis.zrange(key, start, end);
        returnResource(jedis);
        return zrange;
    }
    /**
     *  向名称为 key 的 zset 中添加元素 member，score 用于排序
     			如果该元素已经存在，则根据 score更新该元素的顺序
     * @description: 
     * @param key
     * @param score
     * @param member
     * @return
     */
    public Long zadd(String key,float score, String member) {
        Jedis jedis = getResource();
        Long zadd = jedis.zadd(key, score, member);
        returnResource(jedis);
        return zadd;
    }
    /**
     *  删除名称为key的zset中的元素member 
     * @description: 
     * @param key
     * @param score
     * @param member
     * @return
     */
    public Long  zrem(String key, String member) {
        Jedis jedis = getResource();
        Long zrem = jedis.zrem(key, member);
        returnResource(jedis);
        return zrem;
    }
    /**
     *  返回集合中元素个数 
     * @description: 
     * @param key
     * @return
     */
    public Long zcard(String key) {
        Jedis jedis = getResource();
        Long zadd = jedis.zcard(key);
        returnResource(jedis);
        return zadd;
    }
    /**
     *  判断key 是否存在
     * @description: 
     * @param key
     * @return
     */
    public boolean exists(String key) {
        Jedis jedis = getResource();
        boolean falg = jedis.exists(key);
        returnResource(jedis);
        return falg;
    }
	/**
	 *  清空所有数据库
	 * @description: 
	 * @description: 
	 * @return String
	 */
	public String flushDB(){
		Jedis jedis = getResource();
        String falg = jedis.flushDB();
        returnResource(jedis);
        return falg;
	}
	/**
	 *  查看redis 里面多少数据
	 * @description: 
	 * @return 
	 */
	public Long dbSize(){
		Jedis jedis = getResource();
		Long falg = jedis.dbSize();
        returnResource(jedis);
        return falg;
	}
	/**
	 *  检查是否连接成功
	 * @description: 
	 * @return 
	 */
	public String ping(){
		Jedis jedis = getResource();
        String falg = jedis.ping();
        returnResource(jedis);
        return falg;
	}
    /**
     *  设定一个KEy的活动时间
     * @description: 
     * @param key
     * @param liveTime
     */
	public void expire(String key,  int liveTime){
		Jedis jedis = getResource();
            jedis.expire(key, liveTime);
        returnResource(jedis);
	}
	/**
	 *  key 存活到一个unix时间戳时间
	 * @description: 
	 * @param key
	 * @param liveTime
	 */
	public void expireAt(String key,  long liveTime){
		Jedis jedis = getResource();
          jedis.expireAt(key, liveTime);
        returnResource(jedis);
	} 
	/**
	 *  把jedis放回连接池
	 * @description: 
	 * @param jedis
	 */
    private void returnResource(final Jedis jedis) {
        jedisPool.returnResource(jedis);
    }
    /**
     *  从连接池中获取jedis
     * @description: 
     * @return
     */
    private Jedis getResource() {
        Jedis jedis;
        jedis = jedisPool.getResource();
        return jedis;
    }
   /**
    *  检验连接池是否有效
    * @description: 
    */
    private void checkRedisLiveness() {
        if (jedisPool == null) {
            throw new BaseException("Jedis pool 为空！");
        }
    }
}
